//@author A0096794H
#include "fileProcessing.h"

void FileProcessing::saveFile(){
	ofstream newFile;
	newFile.open("temp.txt", ios::trunc | ios::out);

	for (int i=0; i<TaskList::totalTaskCount(); i++) {
		newFile << TaskList::getTaskAt(i)->stringify() << endl;
	}
	newFile.close();
	remove("KWsave.txt");
	rename("temp.txt", "KWsave.txt");
};

void FileProcessing::loadFile() {
	string desc;
	ifstream file;
	vector<string> vstr;
	vector<int>date;
	vector<int> time;
	Task* task = NULL;
	file.open("KWsave.txt", ios::in | ios::out);
	
	if (file.is_open()) {
		ws(file);
		while (!file.eof()) {
			getline(file, desc);
			splitString(desc,vstr);
			ws(file);
			if(stoi(vstr[0])==FLOATING&&vstr[1]!="")
			{
				task= new FloatingTask(vstr[1]);
				if(stoi(vstr[2]))
				{
					task->markDone();
				}
			}
			else if(stoi(vstr[0])==DEADLINE)
			{
				splitDate(vstr[2],date);
				splitTime(vstr[3],time);
				Time timing=Time(time[0],time[1]);
				Date dates=Date(date[0],date[1],date[2]);
				if(timing==NULL_TIME&&dates.isValidDate())
				{
					task = new DeadlineTask(vstr[1],dates);
				}
				else if(dates.isValidDate()&&timing.isValidTime()) 
				{
					task = new DeadlineTask(vstr[1],dates,timing);
				}
				else
				{
					throw MESSAGE_ERROR_DEADLINE+MESSAGE_CHECK_USER_GUIDE;
				}
				date.clear();
				time.clear();
				if(stoi(vstr[4]))
				{
					task->markDone();
				}
			}
			else if(stoi(vstr[0])==TIMED)
			{
				splitDate(vstr[2],date);
				splitTime(vstr[3],time);
				splitDate(vstr[4],date);
				splitTime(vstr[5],time);
				Time timing1=Time(time[0],time[1]);
				Time timing2=Time(time[2],time[3]);
				Date dates1=Date(date[0],date[1],date[2]);
				Date dates2=Date(date[3],date[4],date[5]);
				if((timing1==NULL_TIME||timing2==NULL_TIME)&&dates1.isValidDate()&&dates2.isValidDate())
				{
					if(dates1 < dates2)
						task = new TimedTask(vstr[1],Date(date[0],date[1],date[2]),Date(date[3],date[4],date[5]));
					else
					{
						throw MESSAGE_ERROR_TIMEDTASK_DATE+MESSAGE_CHECK_USER_GUIDE;
					}
				}
				else if(timing1.isValidTime()&&timing2.isValidTime()&&dates1.isValidDate()&&dates2.isValidDate())
				{
					if(dates1 < dates2||(dates1==dates2&&timing1 < timing2))
						task = new TimedTask(vstr[1],Date(date[0],date[1],date[2]),timing1,Date(date[3],date[4],date[5]),timing2);
					else
					{
						throw MESSAGE_ERROR_TIMEDTASK+MESSAGE_CHECK_USER_GUIDE;
					}
				}
				else
				{
					throw MESSAGE_ERROR_TIMEDTASK+MESSAGE_CHECK_USER_GUIDE;
				}
				date.clear();
				time.clear();
				if(stoi(vstr[6]))
				{
					task->markDone();
				}
			}
			else
			{
				throw MESSAGE_ERROR_UNIDENTIFIED_TASK+MESSAGE_CHECK_USER_GUIDE;
			}
			TaskList::addTask(task);
			vstr.clear();
		}
	}
	else {
		ofstream newFile("KWsave.txt");
		newFile.close();
	}
	file.close();
};

void FileProcessing::splitString(std::string str, vector<std::string> & vstr)
{
	std::string nextArgument;
	int startIndex = 0;
	int endIndex;
	int length;
	if (str.find(",")==ERROR_PROCESSING_COMMAND)
	{
		endIndex=str.find(" ");
		nextArgument=str.substr(startIndex,endIndex);
		vstr.push_back(nextArgument);
	}
	else{
		do {
			endIndex = str.find(",", startIndex);
			length = endIndex - startIndex;
			nextArgument = str.substr(startIndex, length);
			vstr.push_back(nextArgument);
			startIndex=endIndex+1;
		} while (endIndex != std::string::npos);
	}
}

bool FileProcessing::splitDate(string str,vector<int>& date){
	int startIndex=0;
	int endIndex=str.length();
	string nextArgument;
	if(endIndex!=6)
	{
		throw MESSAGE_LOAD_FAIL_DATE;
	}
	while(startIndex!=endIndex)
	{
		nextArgument=str.substr(startIndex,2);
		date.push_back(stoi(nextArgument));
		startIndex+=2;
	}
	return true;
};

bool FileProcessing::splitTime(string str,vector<int>& time){
	int startIndex=0;
	int endIndex=str.length();
	string nextArgument;
	if(endIndex!=4)
	{
		throw MESSAGE_LOAD_FAIL_TIME;
	}
	while(startIndex!=endIndex)
	{
		nextArgument=str.substr(startIndex,2);
		time.push_back(stoi(nextArgument));
		startIndex+=2;
	}
	return true;
};